<!doctype html>

<meta charset="utf-8">
<title>Pigsty流程图展示</title>

<script src="http://d3js.org/d3.v3.js"></script>
<script src="dagre-d3.js"></script>
<script src="http://cpettitt.github.io/project/graphlib-dot/latest/graphlib-dot.min.js"></script>

<style>
svg {
  border: 1px solid #999;
  overflow: hidden;
}

text {
  font-weight: 300;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
  font-size: 14px;
}

.node rect {
  stroke: #333;
  stroke-width: 2px;
  fill: #fff;
}

.edgeLabel rect {
  fill: #fff;
}

.edgePath path {
  stroke: #333;
  stroke-width: 1.5px;
  fill: none;
}
</style>

<style>
h1, h2 {
  color: #333;
}

textarea {
  width: 800px;
}

label {
  margin-top: 1em;
  display: block;
}

.error {
  color: red;
}
</style>

<body onLoad="tryDraw();">

<span style='color:red;'>声明:图标展示采用dagre-d3, 原作者:cpettitt, 项目地址:https://github.com/cpettitt/dagre-d3 </span>
<h1>Pigsty 流程图展示</h1>

<form>
  <label for="inputGraph">请输入流程图定义:</label>
  <textarea id="inputGraph" rows="5" style="display: block" onKeyUp="tryDraw();">
/* Example */
digraph {
    /* Note: HTML labels do not work in IE, which lacks support for &lt;foreignObject&gt; tags. */
    A [label="<div style='padding: 10px;'>A <span style='font-size:32px'>Big</span> <span style='color:red;'>HTML</span> Source!</div>"];
    C;
    E [label="A sink"];
    A -> B -> C;
    B -> D -> E;
    C -> E;
    A -> D [label="<div>A multi-rank <span style='color:blue;'>HTML</span> edge!</div>"];
}
  </textarea>

</form>

<h2>生成流程图:</h2>

<svg width=800 height=600>
  <g transform="translate(20, 20)"/>
</svg>

<script>
// Input related code goes here

function graphToURL() {
  var elems = [window.location.protocol, '//',
               window.location.host,
               window.location.pathname,
               '?'];

  var queryParams = [];
  if (debugAlignment) {
    queryParams.push('alignment=' + debugAlignment);
  }
  queryParams.push('graph=' + encodeURIComponent(inputGraph.value));
  elems.push(queryParams.join('&'));

  return elems.join('');
}

var inputGraph = document.querySelector("#inputGraph");

var graphLink = d3.select("#graphLink");

var oldInputGraphValue;

var graphRE = /[?&]graph=([^&]+)/;
var graphMatch = window.location.search.match(graphRE);
if (graphMatch) {
  inputGraph.value = decodeURIComponent(graphMatch[1]);
}
var debugAlignmentRE = /[?&]alignment=([^&]+)/;
var debugAlignmentMatch = window.location.search.match(debugAlignmentRE);
var debugAlignment;
if (debugAlignmentMatch) debugAlignment = debugAlignmentMatch[1];

function tryDraw() {
  var result;
  if (oldInputGraphValue !== inputGraph.value) {
    inputGraph.setAttribute("class", "");
    oldInputGraphValue = inputGraph.value;
    try {
      result = graphlibDot.parse(inputGraph.value);
    } catch (e) {
      inputGraph.setAttribute("class", "error");
      throw e;
    }

    if (result) {
      // Save link to new graph
      graphLink.attr("href", graphToURL());

      // Cleanup old graph
      var svg = d3.select("svg");

      var renderer = new dagreD3.Renderer();

      // Handle debugAlignment
      renderer.postLayout(function(graph) {
        if (debugAlignment) {
          // First find necessary delta...
          var minX = Math.min.apply(null, graph.nodes().map(function(u) {
            var value = graph.node(u);
            return value[debugAlignment] - value.width / 2;
          }));

          // Update node positions
          graph.eachNode(function(u, value) {
            value.x = value[debugAlignment] - minX;
          });

          // Update edge positions
          graph.eachEdge(function(e, u, v, value) {
            value.points.forEach(function(p) {
              p.x = p[debugAlignment] - minX;
            });
          });
        }
      });

      // Uncomment the following line to get straight edges
      //renderer.edgeInterpolate('linear');

      // Custom transition function
      function transition(selection) {
        return selection.transition().duration(500);
      }

      renderer.transition(transition);

      var layout = renderer.run(result, svg.select("g"));
      transition(d3.select("svg"))
        .attr("width", layout.graph().width + 40)
        .attr("height", layout.graph().height + 40)
    }
  }
}
</script>
